<template>
  <div class="area-content" ref="areaContent">
    <el-card style="min-width: 240px">
      <template #header>
        <div class="card-header">
          <span>区域管理</span>
          <el-button type="primary" :icon="FolderAdd" size="small" @click="drawArea"
            >添加</el-button
          >
        </div>
      </template>
      <table>
        <tr
          v-for="area in areaList"
          :key="area.id"
          @click="flyToAreaCenter(area)"
        >
          <td>{{ area.name }}</td>
          <td>
            <span v-if="!area.isEdit">{{ area.count }}辆</span>
            <el-input
              type="number"
              min="0"
              v-model="area.count"
              style="width: 80px"
              v-if="area.isEdit"
              @blur="area.isEdit = false"
            />
          </td>
          <td>
            <el-button type="info" size="small" @click.stop="area.isEdit = true"
              >编辑</el-button
            >
            <el-button type="danger" size="small" @click.stop="deleteArea(area)"
              >删除</el-button
            >
          </td>
        </tr>
      </table>
    </el-card>
  </div>
</template>

<script setup>
import { onMounted, ref, onUnmounted, createApp, watch } from "vue";
import { storeToRefs } from "pinia";
import { ElInput, ElButton } from "element-plus";
import mapboxgl from "mapbox-gl";
import { getAreas, getCars, deleteAreaById } from "@/api/api";
import * as turf from "@turf/turf";
import { FolderAdd } from "@element-plus/icons-vue";
import { useMapStore, usePostStore } from "@/stores";
import InputPopup from "@/components/InputPopup.vue";
const mapStore = useMapStore();
const map = mapStore.Map;
const draw = mapStore.Draw;
const postStore = usePostStore();
const { updatePostAreaResult } = postStore;
const { postAreaResult } = storeToRefs(postStore);
const areaContent = ref(null);
const areaList = ref([]);

let selectLayerId = "1";
let orginFillColor = "#ABA7A5";
onMounted(async () => {
  areaContent.value.style.top = window.innerHeight * 0.07 + "px";
  const areas = await getAreas();
  //渲染区域列表
  await renderAreaList(areas);
  addAreaAndTextMarker();
});
//组件消失
onUnmounted(() => {
  map.off("draw.create");
  map.getLayer(selectLayerId) &&
    map.setPaintProperty(selectLayerId, "fill-color", orginFillColor);
  selectLayerId = '1';
  //遍历areaList 移除所有的图层和source
  areaList.value.length && areaList.value.forEach(areaObj=>{
    removeLayerAndSource(areaObj.id);
  })
});

//点击删除按钮删除对应的区域
const deleteArea = async (areaObj) => {
  //格局ii占到对应的图层和标注信息及对应的source
  const id = areaObj.id;
  removeLayerAndSource(id);
  //发送删除的请求
  const delRes = await deleteAreaById(id.slice(4));
  //更新列表
  const areas = await getAreas();
  renderAreaList(areas);
};
//点击飞往对应的位置
const flyToAreaCenter = (areaObj) => {
  //找到上一个选中的图层并修改回原来的样式
  map.getLayer(selectLayerId) &&
    map.setPaintProperty(selectLayerId, "fill-color", orginFillColor);
  selectLayerId = areaObj.id + "layer-fill";
  map.getLayer(selectLayerId) &&
    map.setPaintProperty(selectLayerId, "fill-color", "#24ADF3");
  const center = turf.centroid(turf.polygon(areaObj.coordinates)).geometry
    .coordinates;
  map.flyTo({
    center: center,
    duration: 1000,
    speed: 0.5,
    pitch: 30,
  });
};
//绘制多边形区域
const drawArea = () => {
  map.off("draw.create");
  map.addControl(draw, "top-left");
  //家伙区画笔
  draw.changeMode("draw_polygon");
  //添加
  map.on("draw.create", (e) => {
    const polygon = turf.polygon(e.features[0].geometry.coordinates);
    const center = turf.centroid(polygon).geometry.coordinates;
    const div = document.createElement("div");
    const markerEle = createApp(InputPopup, {
      coordinates: e.features[0].geometry.coordinates,
    });
    //事件监听
    markerEle.use(ElButton);
    markerEle.use(ElInput);
    markerEle.mount(div);
    const popup = new mapboxgl.Popup({
      closeOnClick: false,
    })
      .setDOMContent(div)
      .setLngLat(center)
      .addTo(map);

    const unwatch = watch(
      postAreaResult,
      async () => {
        popup.remove();
        unwatch();
        updatePostAreaResult(false);
        //清除绘制的多边形
        draw.deleteAll();
        //移除画笔和对应的监听事件
        map.removeControl(draw);
        //重新渲染数据
        const areas = await getAreas();
        await renderAreaList(areas);
        addAreaAndTextMarker();
      },
      { deep: true }
    );
  });
};
//渲染区域列表
const renderAreaList = async (areas) => {
  //获取所有的car数据
  const carData = await getCars({});
  //遍历所有的区域数据
  areas.forEach((area) => {
    const polygon = turf.polygon(area.coordinates);
    const areaObj = {};
    areaObj.id = "area" + area.id;
    areaObj.name = area.name;
    areaObj.isEdit = ref(false);
    areaObj.count = ref(0);
    areaObj.coordinates = area.coordinates;
    carData.forEach((car) => {
      const point = turf.point(car.coordinates);
      const isIn = turf.booleanPointInPolygon(point, polygon);
      if (isIn) {
        areaObj.count.value++;
      }
    });
    areaList.value.push(areaObj);
  });
};
//添加区域图层和文字标注图层
const addAreaAndTextMarker = () => {
  areaList.value.length &&
    areaList.value.forEach((areaObj) => {
      //如果有数据和图层则先移除
      removeLayerAndSource(areaObj.id);
      const polygon = turf.polygon(areaObj.coordinates);
      const center = turf.point(turf.centroid(polygon).geometry.coordinates, {
        name: areaObj.name,
      });
      //添加多边形
      map.addSource(areaObj.id + "source-fill", {
        type: "geojson",
        data: polygon,
      });
      map.addLayer({
        id: areaObj.id + "layer-fill",
        source: areaObj.id + "source-fill",
        type: "fill",
        paint: {
          "fill-color": "#ABA7A5",
          "fill-opacity": 0.6,
        },
      });
      //添加文字标注
      map.addSource(areaObj.id + "source-text", {
        type: "geojson",
        data: center,
      });
      map.addLayer({
        id: areaObj.id + "layer-text",
        source: areaObj.id + "source-text",
        type: "symbol",
        layout: {
          "text-field": ["get", "name"],
        },
        paint: {
          // 修改文字的颜色
          "text-color": "white",
        },
      });
    });
};
const removeLayerAndSource = (id) => {
  map.getLayer(id + "layer-fill") && map.removeLayer(id + "layer-fill");
  map.getSource(id + "source-fill") && map.removeSource(id + "source-fill");
  map.getLayer(id + "layer-text") && map.removeLayer(id + "layer-text");
  map.getSource(id + "source-text") && map.removeSource(id + "source-text");
};
</script>

<style scoped>
.area-content {
  position: absolute;
  right: 40px;
  height: 300px;
  overflow-y: scroll;
  z-index: 10;
}
.area-content .card-header {
  position: sticky;
  top: 10px;
  display: flex;
  justify-content: space-between;
}
.area-content table {
  width: 100%;
  border: none; /* 去除表格边框 */
  border-collapse: collapse; /* 合并边框 */
}
.area-content table tr:hover {
  cursor: pointer;
  background-color: #aba7a5;
  opacity: 0.6;
}
.area-content table td {
  border: none;
  padding: 10px;
}
</style>
